#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
部署管理器模块
统一管理各种部署引擎和部署流程
"""

import os
import sys
import time
import json
from typing import Dict, List, Optional, Any, Union
from dataclasses import dataclass
from enum import Enum

# 添加项目根目录到路径
current_dir = os.path.dirname(os.path.abspath(__file__))
project_root = os.path.dirname(os.path.dirname(current_dir))
sys.path.insert(0, project_root)

from core.utils import color_green, color_red, color_blue, color_yellow
from modules.automation.automated_deployment_engine import AutomatedDeploymentEngine, AutomationLevel
from modules.automation.batch_deployment_engine import BatchDeploymentEngine
from modules.automation.one_click_deployment import OneClickDeployment
from modules.automation.deployment_verification import DeploymentVerifier
from modules.automation.emergency_cleanup import EmergencyCleanup


class DeploymentMode(Enum):
    """部署模式"""
    AUTOMATED = "automated"      # 自动化部署
    BATCH = "batch"             # 批量部署
    ONE_CLICK = "one_click"     # 一键部署
    MANUAL = "manual"           # 手动部署


class DeploymentStrategy(Enum):
    """部署策略"""
    CONSERVATIVE = "conservative"  # 保守策略
    BALANCED = "balanced"         # 平衡策略
    AGGRESSIVE = "aggressive"     # 激进策略
    CUSTOM = "custom"            # 自定义策略


@dataclass
class DeploymentConfig:
    """部署配置"""
    mode: DeploymentMode
    strategy: DeploymentStrategy
    automation_level: AutomationLevel
    risk_threshold: float = 0.7
    enable_verification: bool = True
    enable_cleanup: bool = True
    target_types: Optional[List[str]] = None
    custom_params: Optional[Dict[str, Any]] = None


@dataclass
class DeploymentResult:
    """部署结果"""
    success: bool
    deployment_id: str
    mode: DeploymentMode
    strategy: DeploymentStrategy
    deployed_count: int
    failed_count: int
    skipped_count: int
    execution_time: float
    error_message: Optional[str] = None
    deployment_details: Optional[Dict[str, Any]] = None
    verification_result: Optional[Dict[str, Any]] = None


class DeploymentManager:
    """部署管理器"""
    
    def __init__(self):
        """初始化部署管理器"""
        self.automated_engine = None
        self.batch_engine = None
        self.one_click_engine = None
        self.verifier = None
        self.cleanup_engine = None
        
        # 部署历史
        self.deployment_history: List[DeploymentResult] = []
        
        # 当前配置
        self.current_config: Optional[DeploymentConfig] = None
        
        color_blue("🚀 部署管理器已初始化")
    
    def initialize_engines(self):
        """初始化部署引擎"""
        try:
            # 初始化自动化部署引擎
            self.automated_engine = AutomatedDeploymentEngine()
            
            # 初始化批量部署引擎
            self.batch_engine = BatchDeploymentEngine()
            
            # 初始化一键部署引擎
            self.one_click_engine = OneClickDeployment()
            
            # 初始化验证器
            self.verifier = DeploymentVerifier()
            
            # 初始化清理引擎
            self.cleanup_engine = EmergencyCleanup()
            
            color_green("✓ 所有部署引擎初始化完成")
            return True
            
        except Exception as e:
            color_red(f"部署引擎初始化失败: {e}")
            return False
    
    def configure_deployment(self, config: DeploymentConfig):
        """配置部署参数"""
        self.current_config = config
        
        # 配置自动化引擎
        if self.automated_engine:
            self.automated_engine.set_automation_level(config.automation_level)
        
        color_blue(f"部署配置已更新: {config.mode.value} 模式")
    
    def deploy(self, config: Optional[DeploymentConfig] = None) -> DeploymentResult:
        """执行部署"""
        if config:
            self.configure_deployment(config)
        
        if not self.current_config:
            raise ValueError("未配置部署参数")
        
        # 确保引擎已初始化
        if not self.automated_engine:
            if not self.initialize_engines():
                return DeploymentResult(
                    success=False,
                    deployment_id="",
                    mode=self.current_config.mode,
                    strategy=self.current_config.strategy,
                    deployed_count=0,
                    failed_count=0,
                    skipped_count=0,
                    execution_time=0,
                    error_message="引擎初始化失败"
                )
        
        start_time = time.time()
        deployment_id = f"deploy_{int(start_time)}"
        
        color_blue(f"🚀 开始执行 {self.current_config.mode.value} 部署")
        
        try:
            # 根据模式选择部署引擎
            if self.current_config.mode == DeploymentMode.AUTOMATED:
                result = self._execute_automated_deployment()
            elif self.current_config.mode == DeploymentMode.BATCH:
                result = self._execute_batch_deployment()
            elif self.current_config.mode == DeploymentMode.ONE_CLICK:
                result = self._execute_one_click_deployment()
            else:
                raise ValueError(f"不支持的部署模式: {self.current_config.mode}")
            
            execution_time = time.time() - start_time
            
            # 创建部署结果
            deployment_result = DeploymentResult(
                success=result.get('success', False),
                deployment_id=deployment_id,
                mode=self.current_config.mode,
                strategy=self.current_config.strategy,
                deployed_count=result.get('deployed_count', 0),
                failed_count=result.get('failed_count', 0),
                skipped_count=result.get('skipped_count', 0),
                execution_time=execution_time,
                deployment_details=result
            )
            
            # 执行验证（如果启用）
            if self.current_config.enable_verification and deployment_result.success:
                verification_result = self._verify_deployment(result)
                deployment_result.verification_result = verification_result
            
            # 记录部署历史
            self.deployment_history.append(deployment_result)
            
            if deployment_result.success:
                color_green(f"✓ 部署完成: {deployment_result.deployed_count} 个成功")
            else:
                color_yellow(f"⚠️ 部署部分成功: {deployment_result.deployed_count} 个成功, {deployment_result.failed_count} 个失败")
            
            return deployment_result
            
        except Exception as e:
            execution_time = time.time() - start_time
            color_red(f"部署失败: {e}")
            
            deployment_result = DeploymentResult(
                success=False,
                deployment_id=deployment_id,
                mode=self.current_config.mode,
                strategy=self.current_config.strategy,
                deployed_count=0,
                failed_count=1,
                skipped_count=0,
                execution_time=execution_time,
                error_message=str(e)
            )
            
            self.deployment_history.append(deployment_result)
            return deployment_result
    
    def _execute_automated_deployment(self) -> Dict[str, Any]:
        """执行自动化部署"""
        try:
            # 使用自动化部署引擎
            deployment_plan = self.automated_engine.execute_automated_deployment(
                risk_threshold=self.current_config.risk_threshold
            )
            
            # 统计结果
            deployed_count = len([t for t in deployment_plan.deployment_tasks 
                                if t.status.value == "success"])
            failed_count = len([t for t in deployment_plan.deployment_tasks 
                              if t.status.value == "failed"])
            skipped_count = len([t for t in deployment_plan.deployment_tasks 
                               if t.status.value == "skipped"])
            
            return {
                'success': deployed_count > 0,
                'deployed_count': deployed_count,
                'failed_count': failed_count,
                'skipped_count': skipped_count,
                'deployment_plan': deployment_plan,
                'engine_type': 'automated'
            }
            
        except Exception as e:
            return {
                'success': False,
                'deployed_count': 0,
                'failed_count': 1,
                'skipped_count': 0,
                'error': str(e),
                'engine_type': 'automated'
            }
    
    def _execute_batch_deployment(self) -> Dict[str, Any]:
        """执行批量部署"""
        try:
            # 检测环境
            if not self.batch_engine.detect_target_environment():
                raise Exception("环境检测失败")
            
            # 生成部署计划
            if not self.batch_engine.generate_deployment_plan(self.current_config.target_types):
                raise Exception("部署计划生成失败")
            
            # 执行部署
            success = self.batch_engine.execute_batch_deployment(auto_confirm=True)
            
            # 获取结果摘要
            summary = self.batch_engine.get_deployment_summary()
            
            deployed_count = len(summary.get('deployed_backdoors', []))
            
            return {
                'success': success and deployed_count > 0,
                'deployed_count': deployed_count,
                'failed_count': 0 if success else 1,
                'skipped_count': 0,
                'deployment_summary': summary,
                'engine_type': 'batch'
            }
            
        except Exception as e:
            return {
                'success': False,
                'deployed_count': 0,
                'failed_count': 1,
                'skipped_count': 0,
                'error': str(e),
                'engine_type': 'batch'
            }
    
    def _execute_one_click_deployment(self) -> Dict[str, Any]:
        """执行一键部署"""
        try:
            # 执行一键部署
            success = self.one_click_engine.execute_deployment()
            
            # 获取部署记录
            records = getattr(self.one_click_engine, 'deployment_records', [])
            deployed_count = len(records)
            
            return {
                'success': success,
                'deployed_count': deployed_count,
                'failed_count': 0 if success else 1,
                'skipped_count': 0,
                'deployment_records': records,
                'engine_type': 'one_click'
            }
            
        except Exception as e:
            return {
                'success': False,
                'deployed_count': 0,
                'failed_count': 1,
                'skipped_count': 0,
                'error': str(e),
                'engine_type': 'one_click'
            }
    
    def _verify_deployment(self, deployment_result: Dict[str, Any]) -> Dict[str, Any]:
        """验证部署结果"""
        try:
            color_blue("🔍 正在验证部署结果...")
            
            # 运行验证
            verification_summary = self.verifier.run_comprehensive_verification()
            
            color_green("✓ 部署验证完成")
            return verification_summary
            
        except Exception as e:
            color_yellow(f"⚠️ 部署验证失败: {e}")
            return {
                'success': False,
                'error': str(e)
            }
    
    def cleanup_deployment(self, deployment_id: Optional[str] = None, mode: str = "fast") -> bool:
        """清理部署"""
        try:
            color_blue(f"🧹 开始清理部署 (模式: {mode})")
            
            if self.cleanup_engine:
                success = self.cleanup_engine.execute_cleanup(mode)
                
                if success:
                    color_green("✓ 部署清理完成")
                else:
                    color_yellow("⚠️ 部署清理部分完成")
                
                return success
            else:
                color_yellow("⚠️ 清理引擎未初始化")
                return False
                
        except Exception as e:
            color_red(f"清理失败: {e}")
            return False
    
    def get_deployment_status(self) -> Dict[str, Any]:
        """获取部署状态"""
        total_deployments = len(self.deployment_history)
        successful_deployments = len([d for d in self.deployment_history if d.success])
        
        return {
            'total_deployments': total_deployments,
            'successful_deployments': successful_deployments,
            'success_rate': successful_deployments / total_deployments if total_deployments > 0 else 0,
            'last_deployment': self.deployment_history[-1] if self.deployment_history else None,
            'current_config': self.current_config
        }
    
    def get_deployment_history(self) -> List[DeploymentResult]:
        """获取部署历史"""
        return self.deployment_history
    
    def export_deployment_report(self, file_path: Optional[str] = None) -> str:
        """导出部署报告"""
        if not file_path:
            file_path = f"deployment_report_{int(time.time())}.json"
        
        report_data = {
            'deployment_status': self.get_deployment_status(),
            'deployment_history': [
                {
                    'deployment_id': d.deployment_id,
                    'success': d.success,
                    'mode': d.mode.value,
                    'strategy': d.strategy.value,
                    'deployed_count': d.deployed_count,
                    'failed_count': d.failed_count,
                    'execution_time': d.execution_time,
                    'error_message': d.error_message
                }
                for d in self.deployment_history
            ]
        }
        
        try:
            with open(file_path, 'w', encoding='utf-8') as f:
                json.dump(report_data, f, ensure_ascii=False, indent=2)
            
            color_green(f"✓ 部署报告已导出: {file_path}")
            return file_path
            
        except Exception as e:
            color_red(f"报告导出失败: {e}")
            return ""


# 便捷函数
def quick_deploy(mode: str = "one_click", strategy: str = "balanced", 
                automation_level: str = "semi_auto") -> DeploymentResult:
    """快速部署"""
    manager = DeploymentManager()
    
    config = DeploymentConfig(
        mode=DeploymentMode(mode),
        strategy=DeploymentStrategy(strategy),
        automation_level=AutomationLevel(automation_level)
    )
    
    return manager.deploy(config)


def emergency_cleanup(mode: str = "fast") -> bool:
    """应急清理"""
    manager = DeploymentManager()
    manager.initialize_engines()
    return manager.cleanup_deployment(mode=mode)


# 测试函数
def test_deployment_manager():
    """测试部署管理器"""
    color_blue("🧪 测试部署管理器")
    
    manager = DeploymentManager()
    
    # 测试初始化
    if not manager.initialize_engines():
        color_red("引擎初始化失败")
        return False
    
    # 测试配置
    config = DeploymentConfig(
        mode=DeploymentMode.ONE_CLICK,
        strategy=DeploymentStrategy.BALANCED,
        automation_level=AutomationLevel.SEMI_AUTO,
        risk_threshold=0.7
    )
    
    manager.configure_deployment(config)
    
    # 获取状态
    status = manager.get_deployment_status()
    color_green(f"✓ 部署管理器测试完成: {status}")
    
    return True


if __name__ == "__main__":
    test_deployment_manager()